<!--
 * @Author: cjh
 * @Date: 2022-04-23 09:57:17
 * @LastEditors: cjh
 * @LastEditTime: 2022-04-23 21:20:33
 * @Description: 
-->
<template>
  <h3>{{ title }}</h3>
  <p>名字：{{ name }}</p>
  <p>年龄：{{ foo + boo }}</p>
  <p>电话：{{ phone }}</p>
  <p>工作：{{ work }}</p>
  <p>computed: {{ cNum }}</p>
  <p>watchRef: {{ watchNum }}</p>
  <p>watchReactive: {{ num }}</p>
</template>

<script>
import {
  ref,
  reactive,
  readonly,
  isRef,
  unref,
  isReactive,
  toRef,
  toRefs,
  computed,
  watch,
} from "vue";
export default {
  name: "App",
  setup() {
    const title = ref("hello world Vue3");
    // 检查某个值是否为 ref
    if (isRef(title)) {
      console.log("15", "是ref");
    } else {
      console.log("17", "不是ref");
    }
    // 判断是否为ref 是就直接返回 val = isRef(val) ? val.value : val
    let unrefName = unref(title);

    const reactiveData = reactive({
      name: "chijunhai",
      foo: 10,
      boo: 10,
      phone: "18605767075",
      work: "搬砖仔",
    });
    console.log("26", reactiveData);
    // 使用toRef方法后，所转换的是引用类型，也就是源数据也会被影响
    const fooData = toRef(reactiveData, "foo");
    fooData.value++;
    console.log("29", reactiveData.foo);

    reactiveData.foo++;
    console.log("33", fooData.value);

    // 检查某个值是否为 reactive
    if (isReactive(reactiveData)) {
      console.log("37", "是reactive");
    } else {
      console.log("39", "不是reactive");
    }

    // 只读代理
    const copyData = readonly(reactiveData);
    // 更改该只读副本将会失败，并会得到一个警告
    copyData.foo++; // warning
    console.log("58", copyData);

    // computed 例子
    const num = ref(10);
    const cNum = computed({
      get: () => num.value + 90,
      set: (val) => num.value + val,
    });

    setTimeout(() => {
      num.value = 1;
    }, 2000);

    // watch ref类型的例子;
    const watchNum = ref(5);
    watch(watchNum, (newVal, oldVal) => {
      console.log(newVal, oldVal);
    });

    setTimeout(() => {
      watchNum.value = 4;
    }, 2000);

    // watch reactive 类型的例子;
    const watchData = reactive({
      num: 10,
      num2: 100,
    });

    // 单个写法
    watch(
      () => watchData.num,
      (newVal, oldVal) => {
        console.log(newVal, oldVal);
      }
    );

    // 多个写法
    watch(
      [() => watchData.num, () => watchData.num2],
      // 第一组是新数据，第二组是原始数据
      ([newNum, oldNum], [newNum2, oldNum2]) => {
        console.log("num" + newNum, oldNum);
        console.log("num" + newNum2, oldNum2);
      }
    );

    setTimeout(() => {
      watchData.num++;
    }, 2000);

    return {
      title,
      unrefName,
      watchNum,
      ...toRefs(watchData),
      ...toRefs(reactiveData),
      cNum,
    };
  },
};
</script>
